package com.battle.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.battle.pojo.entity.DataLabelingTask;
import com.battle.pojo.entity.User;
import com.battle.pojo.param.dataLabelingTask.*;
import com.battle.pojo.vo.dataLabelingTask.*;
import com.battle.pojo.dto.dataLabelingTask.*;
import com.battle.pojo.vo.personWarCase.GetPersonWarCaseListVo;
import com.battle.service.repository.in.DataLabelingTaskRepository;
import com.battle.service.repository.in.UserRepository;
import com.battle.service.service.in.DataLabelingTaskService;
import com.battle.service.utils.ExcelUtils;
import jakarta.servlet.http.HttpServletResponse;
import nirvana.core.domains.vo.PageResult;
import nirvana.core.utils.ids.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 【描 述】：数据标注任务服务
 * 【环 境】：J2SE 17
 * 【详 细】：
 */
@Service
public class DataLabelingTaskServiceImpl implements DataLabelingTaskService {

    private final DataLabelingTaskRepository dataLabelingTaskRepository;
    private final UserRepository userRepository;

    public DataLabelingTaskServiceImpl(DataLabelingTaskRepository dataLabelingTaskRepository, UserRepository userRepository) {
        this.dataLabelingTaskRepository = dataLabelingTaskRepository;
        this.userRepository = userRepository;
    }


    /**
     * 创建数据标注任务
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createDataLabelingTask(CreateDataLabelingTaskParam param) {
        List<DataLabelingTask> dataLabelingTaskList = new ArrayList<>();

        for (Long principal : param.getPrincipal()) {
            DataLabelingTask dataLabelingTask = new DataLabelingTask();
            Long id = IdGenerator.SNOW.generate();
            dataLabelingTask.setName(param.getName());
            dataLabelingTask.setId(id);
            dataLabelingTask.setPrincipal(principal);
            dataLabelingTask.setIsLabeling(false);
            dataLabelingTaskList.add(dataLabelingTask);
        }
        if (CollectionUtil.isNotEmpty(dataLabelingTaskList)){
            dataLabelingTaskRepository.saveBatch(dataLabelingTaskList);
        }
    }

    /**
     * 修改数据标注任务
     *
     * @param param
     */
    @Override
    public void editDataLabelingTask(EditDataLabelingTaskParam param) {
        Long id = param.getId();
        DataLabelingTask dataLabelingTask = dataLabelingTaskRepository.getByIdCheck(id);
        BeanUtils.copyProperties(param, dataLabelingTask);
        dataLabelingTask.setIsLabeling(true);
        dataLabelingTask.setLabelingTime(LocalDateTime.now());
        dataLabelingTaskRepository.edit(dataLabelingTask);
    }

    /**
     * 移除数据标注任务
     *
     * @param id
     */
    @Override
    public void removeDataLabelingTask(Long id) {
        dataLabelingTaskRepository.removeById(id);
    }

    /**
     * 启动/禁用数据标注任务
     *
     * @param id
     */
    @Override
    public void enabledDataLabelingTask(Long id) {
        DataLabelingTask dataLabelingTask = dataLabelingTaskRepository.getByIdCheck(id);
        dataLabelingTask.setIsDisable(!dataLabelingTask.getIsDisable());
        dataLabelingTaskRepository.edit(dataLabelingTask);
    }

    /**
     * 获取数据标注任务详情
     *
     * @param id
     * @return
     */
    @Override
    public GetDataLabelingTaskVo getDataLabelingTask(Long id) {
        DataLabelingTask dataLabelingTask = dataLabelingTaskRepository.getByIdCheck(id);
        GetDataLabelingTaskVo vo = new GetDataLabelingTaskVo();
        BeanUtils.copyProperties(dataLabelingTask, vo);
        return vo;
    }

    /**
     * 获取数据标注任务 列表
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<GetDataLabelingTaskListVo> getDataLabelingTaskList(GetDataLabelingTaskListParam param) {

        SelectDataLabelingTaskDto dto = new SelectDataLabelingTaskDto();
        BeanUtils.copyProperties(param, dto);
        Page<DataLabelingTask> page = dataLabelingTaskRepository.selectDataLabelingTask(dto);
        List<DataLabelingTask> dataLabelingTaskList = page.getRecords();
        List<GetDataLabelingTaskListVo> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(dataLabelingTaskList)) {
            List<Long> userIds = new ArrayList<>();
            dataLabelingTaskList.forEach(v -> {
                userIds.add(v.getCreator());
                userIds.add(v.getPrincipal());
            });

            Map<Long, User> userMap = userRepository.getMap(userIds);
            for (DataLabelingTask dataLabelingTask : dataLabelingTaskList) {
                GetDataLabelingTaskListVo vo = new GetDataLabelingTaskListVo();
                GetDataLabelingTaskVo task = getDataLabelingTask(dataLabelingTask.getId());
                BeanUtils.copyProperties(task, vo);
                User user = userMap.get(dataLabelingTask.getCreator());
                if (user!=null){
                    vo.setCreateName(user.getName());
                }
                User principal = userMap.get(dataLabelingTask.getPrincipal());
                if (principal!=null){
                    vo.setPrincipalName(principal.getName());
                }
                if (task.getTask()!=null){
                    vo.setTaskUrl(task.getTask().getUrl());
                }
                vo.setCreateTime(dataLabelingTask.getCreateTime());
                list.add(vo);
            }
        }

        return new PageResult<>(list, page);

    }

    @Override
    public void export(GetDataLabelingTaskListParam param, HttpServletResponse response) throws IOException {
        param.setSize(Long.MAX_VALUE);
        PageResult<GetDataLabelingTaskListVo> pageResult = getDataLabelingTaskList(param);
        List<GetDataLabelingTaskListVo> list = pageResult.getRecords();
        ExcelUtils.exportExcel(list, "数据标注", "数据标注", GetDataLabelingTaskListVo.class, "数据标注",response);

    }

    /**
     * 获取数据标注任务下拉列表
     *
     * @param param
     * @return
     */
    @Override
    public List<GetDataLabelingTaskDownListVo> getDataLabelingTaskDownList(GetDataLabelingTaskDownListParam param) {
        DataLabelingTask po = new DataLabelingTask();
        if (param != null) {
            BeanUtils.copyProperties(param, po);
        }
        List<DataLabelingTask> dataLabelingTaskList = dataLabelingTaskRepository.getListByEntity(po);

        List<GetDataLabelingTaskDownListVo> list = new ArrayList<>();
        for (DataLabelingTask dataLabelingTask : dataLabelingTaskList) {
            GetDataLabelingTaskDownListVo vo = new GetDataLabelingTaskDownListVo();
            BeanUtils.copyProperties(dataLabelingTask, vo);
            list.add(vo);
        }
        return list;
    }

    /**
     * 获得所有的任务数据
     * @return
     */
    @Override
    public GetDataLabelingGraphVo getDataLabelingGraph() {
        DataLabelingTask task=new DataLabelingTask();

        List<DataLabelingTask> listByEntity = dataLabelingTaskRepository.getListByEntity(task);
        GetDataLabelingGraphVo vo=new GetDataLabelingGraphVo();
        vo.setTaskNumber(0);
        vo.setUnfinishedTaskNumber(0);
        vo.setCompletedTaskNumber(0);

        if (CollectionUtil.isNotEmpty(listByEntity)){
            vo.setTaskNumber(listByEntity.size());
            Long completedTask = listByEntity.stream().filter(v -> v.getIsLabeling()==true).count();
            if (completedTask!=null){
                vo.setCompletedTaskNumber(completedTask.intValue());
            }
            Long unFinished = listByEntity.stream().filter(v -> v.getIsLabeling()==false).count();
            if (unFinished!=null){
                vo.setUnfinishedTaskNumber(unFinished.intValue());
            }
        }
        return vo;
    }


}



